package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    // 定义一个DatagramSocket类的私有成员变量socket，用于UDP通信。
//    操作网卡都是通过socket对象来完成
    private DatagramSocket socket = null;

    // UdpEchoServer的构造函数，接收一个整型参数port，表示服务器将要监听的端口号。
    public UdpEchoServer(int port) throws SocketException {
        // 实例化DatagramSocket对象，绑定到指定的端口号port上。
        // 这个过程中，如果指定的端口号已经被其他应用占用，将抛出SocketException异常。
        socket = new DatagramSocket(port);
        // 程序启动时，通过调用DatagramSocket的构造函数并传入端口号来绑定该端口。
        // 端口号用于在网络内唯一标识运行的程序，使外界能通过IP地址加端口号找到并与之通信。
//        端口号是一个整数是从1024到65535 (0-1023)保留给系统使用
        // 绑定端口确保所有发送到这个端口的UDP数据包都由这个DatagramSocket实例处理。
    }

    public void start() throws IOException {
        System.out.println("服务器,启动!");
        while(true){
//            每次循环,就是一个请求-响应过程
            // 创建一个DatagramPacket用于接收客户端发送的数据。
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            // 接收客户端发送的数据。当receive方法执行时，它会阻塞，直到一个数据包到达。
            socket.receive(requestPacket);//用于接收数据
            // 将接收到的数据转换成String类型，方便后续处理。
            String request = new String(requestPacket.getData(), 0,
                    requestPacket.getLength());

            // 对接收到的数据进行处理，这里直接将其作为响应数据（回显服务器的特点）。
            String response = process(request);

            // 构造响应数据包，准备发送回客户端。
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
                    response.getBytes().length, requestPacket.getSocketAddress());
            // 发送响应数据包给客户端。
            socket.send(responsePacket);

            // 打印日志，显示请求和响应信息。
            System.out.printf("[%s:%d] req: %s, resp: %s\n",
                    requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }
    }

    public String process(String request) {
        // 直接返回接收到的数据作为响应，实现回显功能。
        return request;
    }

    public static void main(String[] args) throws IOException {
        // 创建服务器实例并启动，监听端口: 6666。
        UdpEchoServer server = new UdpEchoServer(6666);
        server.start();
    }
}

